package arithmetic

import java.math.BigInteger

/**
 * 递归阶乘(非尾递归)
 */
fun recursion(factNum: BigInteger): BigInteger {
    return if (factNum == BigInteger.valueOf(0)) {
        BigInteger.valueOf(1)
    } else {
        factNum.times(recursion(factNum - BigInteger.valueOf(1)))
    }
}

/**
 * 递归阶乘(尾递归优化)
 */
class RecursionTailrec {
    var result: BigInteger = BigInteger.valueOf(1)

    /**
     * tailrec 尾递归优化关键字
     */
    tailrec fun recursionTailrec(factNum: BigInteger) {
        if (factNum == BigInteger.valueOf(0)) {
            result = result.times(BigInteger.valueOf(1))
        } else {
            result = result.times(factNum)
            recursionTailrec(factNum - BigInteger.valueOf(1))
        }
    }
}


fun main(args: Array<String>) {
    //非尾递归层级过多，会抛出异常
//    print(recursion(BigInteger.valueOf(10000)))
    //使用尾递归优化，不会抛出异常
    var rt = RecursionTailrec()
    rt.recursionTailrec(BigInteger.valueOf(100000))
    print(rt.result)

}